﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Options;
using Ninesky.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.Net.Http.Headers;
using System.IdentityModel.Tokens.Jwt;
using Microsoft.IdentityModel.Tokens;
using System.Text;

namespace Ninesky.WebAPI.Authorize
{
    public class NineskyAsyncAuthorizeAttribute : Attribute,IAsyncAuthorizationFilter
    {
        public Task OnAuthorizationAsync(AuthorizationFilterContext context)
        {
            //跳过带有AllowAnonymousAttribute
            if (context.Filters.Any(filter=> filter is IAllowAnonymousFilter))
            {
                return Task.CompletedTask;
            }
            //判断Token是否存在
            string token = null;
            string authorization = context.HttpContext.Request.Headers["Authorization"];
            if (string.IsNullOrEmpty(authorization))
            {
                context.HttpContext.Response.Headers.Add(HeaderNames.WWWAuthenticate, "Bearer error=\"no_token\"");
                context.Result = new StatusCodeResult(401);
                return Task.CompletedTask;
            }
            if (authorization.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase))
            {
                token = authorization.Substring("Bearer ".Length).Trim();
            }
            if (string.IsNullOrEmpty(token))
            {
                context.HttpContext.Response.Headers.Add(HeaderNames.WWWAuthenticate, "Bearer error=\"no_token\"");
                context.Result = new StatusCodeResult(401);
                return Task.CompletedTask;
            }
            var jwtConfig = ((IOptionsMonitor<JwtConfig>)context.HttpContext.RequestServices.GetService(typeof(IOptionsMonitor<JwtConfig>))).CurrentValue;
            //Token是否合法
            JwtSecurityTokenHandler jwtTokenHandler = new JwtSecurityTokenHandler();
            SecurityToken securityToken;
            try
            {
                var claimsPrincipal = jwtTokenHandler.ValidateToken(token, new TokenValidationParameters()
                {
                    ValidateAudience = false,
                    ValidateIssuerSigningKey = true,
                    ValidateLifetime = true,
                    ValidateIssuer = true,
                    ValidIssuer = jwtConfig.Issuer,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(jwtConfig.Secret))

                }, out securityToken);
            }
            catch(Exception ex)
            {
                context.HttpContext.Response.Headers.Add(HeaderNames.WWWAuthenticate, "Bearer error=\"invalid_token\"");
                context.Result = new StatusCodeResult(401);
                return Task.CompletedTask;
            }

            //判断Action权限




            return Task.CompletedTask;
        }
    }
}
